package com.mehdiuz.backend.role.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mehdiuz.backend.commons.utils.Result;
import com.mehdiuz.backend.role.entity.*;
import com.mehdiuz.backend.role.entity.vo.RoleSearchVo;
import com.mehdiuz.backend.role.service.MenuService;
import com.mehdiuz.backend.role.service.RoleMenuService;
import com.mehdiuz.backend.role.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/system/role")
@Api(tags = "角色管理")
public class RoleController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private MenuService menuService;

    @PostMapping("getRoleMenu")
    @ApiOperation(value = "查询当前角色具有的菜单权限")
    @PreAuthorize("hasAuthority('bnt.menu.grant')")
    public Result<List<Long>> getRoleMenu(@RequestBody Role role){
        List<RoleMenu> roleMenuList = roleMenuService.getBaseMapper().selectList(new QueryWrapper<RoleMenu>().eq("role_id", role.getId()));
        List<Long> menuIds;
        List<Menu> menus;
        List<Long> collect = new ArrayList<>();
        if(roleMenuList.size() > 0){
            menuIds = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            menus = menuService.getBaseMapper().selectBatchIds(menuIds);
            menus.forEach(menu -> {
                menuService.findChildren(menu,menus);
            });
            collect = menus.stream().filter(menu -> menu.getChildren().size()==0).map(Menu::getId).collect(Collectors.toList());
        }
        return Result.ok(collect);
    }

    @PostMapping("menuGrant/{roleId}")
    @PreAuthorize("hasAuthority('bnt.menu.grant')")
    @ApiOperation(value = "个体当前角色进行菜单权限分配")
    public Result<Boolean> menuGrant(@PathVariable Long roleId, @RequestBody List<RoleMenu> roleMenus){
        //查询出当前角色具有哪些权限
        List<RoleMenu> roleMenuList = roleMenuService.getBaseMapper().selectList(new QueryWrapper<RoleMenu>().eq("role_id", roleId));
        AtomicBoolean b = new AtomicBoolean(false);
        if(roleMenuList.size() == 0){
            b.set(roleMenuService.saveBatch(roleMenus));
            if(b.get()){
                return Result.ok(b.get());
            }else {
                return Result.fail();
            }
        }else{
            List<Long> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            //原始数据比传入数据多的删除
            roleMenuList.forEach(roleMenu -> {
                if(!menuIds.contains(roleMenu.getMenuId())){
                    b.set(roleMenuService.removeById(roleMenu.getId()));
                }
            });
            //原始数据和传入数据一样的不做处理
            //原始数据比传入数据少的做插入处理,将原始数据和传入数据相同的删掉
            roleMenuList.forEach(role->{
                roleMenus.removeIf(roleMenu -> roleMenu.getRoleId().equals(role.getRoleId()) && roleMenu.getMenuId().equals(role.getMenuId()));
            });

            if(roleMenus.size()>0){
                b.set(roleMenuService.saveBatch(roleMenus));
            }
            if(b.get()){
                return Result.ok(b.get());
            }else {
                return Result.fail();
            }
        }
    }

    @PostMapping("deleteRole")
    @ApiOperation(value = "角色删除")
    @PreAuthorize("hasAuthority('bnt.role.delete')")
    public Result<Boolean> deleteRole(@RequestBody List<Role> roles){
        List<Long> idList = roles.stream().map(Role::getId).collect(Collectors.toList());
        boolean b = false;
        b = roleService.removeByIds(idList);
        if(b){
            return Result.ok(b);
        }else {
            return Result.fail(b);
        }
    }

    @PostMapping("insertRole")
    @ApiOperation(value = "角色添加")
    @PreAuthorize("hasAuthority('bnt.role.insert')")
    public Result<Boolean> insertRole(@RequestBody Role role){
        boolean save = false;
        save = roleService.save(role);
        if(save){
            return Result.ok(save);
        }else {
            return Result.fail(save);
        }
    }

    @PostMapping("updateRole")
    @ApiOperation(value = "角色修改")
    @PreAuthorize("hasAuthority('bnt.role.edit')")
    public Result<Boolean> updateRole(@RequestBody Role role){
        boolean update = false;
        update = roleService.update(role,new QueryWrapper<Role>().eq("id",role.getId()));
        if(update){
            return Result.ok(update);
        }else {
            return Result.fail(update);
        }
    }

    @ApiOperation(value = "角色分页查询")
    @PostMapping("/{page}/{limit}")
    @PreAuthorize("hasAuthority('bnt.role.list')")
    public Result<IPage<Role>> index(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable Long page,

            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable Long limit,

            @ApiParam(name = "roleQueryVo", value = "查询对象", required = false)
                    @RequestBody RoleSearchVo role) {
        Page<Role> pageParam = new Page<>(page, limit);
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(role.getRoleName())){
            queryWrapper.like("role_name",role.getRoleName());
        }
        if(StringUtils.isNotBlank(role.getRoleCode())){
            queryWrapper.like("role_code",role.getRoleCode());
        }
        if(null != role.getCreateTime()){
            if(role.getCreateTime().size() == 2){
                queryWrapper.between("create_time",role.getCreateTime().get(0),role.getCreateTime().get(1));
            }
        }
        if(null != role.getUpdateTime()){
            if(role.getUpdateTime().size() == 2){
                queryWrapper.between("update_time",role.getUpdateTime().get(0),role.getUpdateTime().get(1));
            }
        }
        IPage<Role> pageModel = roleService.page(pageParam,queryWrapper);
        return Result.ok(pageModel);
    }



}
